package net.slavics.maps;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JLabel;
import net.slavics.maps.ifc.IMapa;
import net.slavics.maps.ifc.MapComponent;
import org.apache.log4j.Logger;

/**
 *
 * @author slavic01
 * @version $Revision$
 * $LastChangedDate$ $Author$
 */
public class GridMap extends JLabel {

    static final long serialVersionUID = 451321316L;
    private static Logger _log = Logger.getLogger(GridMap.class);
    private Map<Point, CellMap> listMaps = new HashMap<Point, CellMap>();
    private Point shift;   //Pozice na obrazovce
    private IMapa iMapa;
    protected MapComponent mc;
    //private IGeoTransfer transform=new LineGeoTransfer(1/256d, -58, 1/256d, -125);
    /**
     * Vytvoří oblast s mapama
     */
    private GridMap() {
    //setOpaque(true);			 // DULEZITE !
    }

    public GridMap(MapComponent mpc, IMapa mapa, Point shiftXY) {
        this.mc = mpc;
        this.iMapa = mapa;
        this.shift = new Point(shiftXY);
    }

    void checkMap() {
        mc.addProgressBar("Maps", listMaps.size());
        _log.debug("Size " + this.getSize() + " shiftXY: " + shift);
        Point sektor = new Point(Integer.valueOf(shift.x / iMapa.getWidth()), Integer.valueOf(shift.y / iMapa.getHeight()));
        Dimension dim = new Dimension(1+Integer.valueOf(getSize().width / iMapa.getWidth()), 1 + Integer.valueOf(getSize().height / iMapa.getHeight()));
        for (int y = sektor.y + 0; y <= sektor.y + dim.height; y++) {
            for (int x = sektor.x - 1; x < sektor.x + dim.width; x++) {
                Point newSektor = new Point(x, y);
                if (!listMaps.containsKey(newSektor)) {
                    addCell(new CellMap(this, iMapa, newSektor));
                }
            }
        }
        mc.addProgressBar("Maps", listMaps.size());
        List<Point> rlist = new ArrayList<Point>();
        for (Point p : listMaps.keySet()) {
            if (p.x < sektor.x - 1) {
                rlist.add(p);
                continue;
            }
            if (p.y < sektor.y - 0) {
                rlist.add(p);
                continue;
            }
            if (p.x > sektor.x + dim.width) {
                rlist.add(p);
                continue;
            }
            if (p.y > sektor.y + dim.height) {
                rlist.add(p);
                continue;
            }
        }
        for (Point p : rlist) {
            _log.info("DELETE [" + p.x + "," + p.y + "] " + listMaps.get(p).toString());
            listMaps.remove(p);
        }
        mc.addProgressBar("Maps", listMaps.size());
    }

    public synchronized void addCell(CellMap mp) {
        _log.info("INSERT [" + mp.getSektor().x + "," + mp.getSektor().y + "] " + mp);
        listMaps.put(mp.getSektor(), mp);
    }

    /**
     * Posune mapy o point
     * @param shiftXY
     */
    public void shift(Point shiftXY) {
        _log.debug("Shift " + shiftXY);
        shift.translate(-shiftXY.x, -shiftXY.y);
        this.repaint();
    }

    @Override
    public void paintComponent(Graphics g) {
        _log.debug("Překreslení " + this.getWidth() + "," + this.getHeight());
        checkMap();
        Point sektor0 = new Point(Integer.valueOf(shift.x / iMapa.getWidth()), Integer.valueOf(shift.y / iMapa.getHeight()));
        Point screen0 = new Point(-shift.x % iMapa.getWidth(), -shift.y % iMapa.getHeight());
        for (CellMap mapa : listMaps.values()) {
            Point screen = new Point(screen0.x + iMapa.getWidth() * (mapa.getSektor().x - sektor0.x), screen0.y + iMapa.getHeight() * (mapa.getSektor().y - sektor0.y));
            mapa.show(screen);
            mapa.paint(g);
        }
    }
}
